home *** CD-ROM | disk | FTP | other *** search
- /* -*- C -*-
- ** Amiga Graphics for ASTROLOG
- **
- ** (c)Copyright 1994-95 by Tobias Ferber, All Rights Reserved
- */
-
- /* $VER: $Id: amiga.c,v 1.8 1995/08/11 12:13:49 tf Exp $ */
-
- #include <exec/types.h>
- #include <exec/memory.h>
-
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <intuition/screens.h>
-
- #include <graphics/gfx.h>
- #include <graphics/gfxbase.h>
- #include <graphics/view.h>
-
- #include <stdio.h>
-
- #include "astrolog.h"
- #include "rastport.h"
-
- /*#define NOSCREEN*/
- /* compile with -DNOSCREEN in order to get a window which opens on the Workbench screen
- * and uses ObtainBestPen() to get it's colors. (VERY UNSTABLE!) */
-
- /* Prototypes */
-
- extern ULONG AvailMem(ULONG);
- extern struct Screen *OpenScreenTagList( struct NewScreen *, struct TagItem * );
- extern struct Screen *LockPubScreen( UBYTE * );
- extern VOID UnlockPubScreen( UBYTE *, struct Screen * );
- extern VOID DrawImage( struct RastPort *, struct Image *, WORD, WORD );
- extern struct TextFont *OpenDiskFont( struct TextAttr * );
- extern void CloseFont(struct TextFont *);
- extern void SetFont(struct RastPort *, struct TextFont *);
-
- void StripIntuiMessages( struct MsgPort *mp, struct Window *win );
- void CloseWindowSafely( struct Window *win );
-
- /*
- ** DATA
- */
-
- #define NS_VIEWMODE HIRES|LACE
- #define NS_TYPE CUSTOMSCREEN|SCREENQUIET|AUTOSCROLL /* V36+ ?! */
- #define NS_DEPTH 4 /* Bitplanes for 16 EGA colors */
-
- #if defined(NOSCREEN)
- #define NW_FLAGS WINDOWSIZING|RMBTRAP|REPORTMOUSE|NOCAREREFRESH|ACTIVATE|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH
- #define NW_IDCMP VANILLAKEY|MOUSEBUTTONS|MOUSEMOVE|NEWSIZE|INTUITICKS|CLOSEWINDOW
- #define NW_TYPE WBENCHSCREEN
- #else /* !NOSCREEN */
- #define NW_FLAGS BORDERLESS|WINDOWSIZING|RMBTRAP|REPORTMOUSE|NOCAREREFRESH|ACTIVATE/*|BACKDROP*/
- #define NW_IDCMP VANILLAKEY|MOUSEBUTTONS|MOUSEMOVE|NEWSIZE|INTUITICKS/*|CLOSEWINDOW*/
- #define NW_TYPE CUSTOMSCREEN
- #endif /* !NOSCREEN */
-
- static UBYTE DisplayTitle[]= "Astrolog";
-
- /*
- * Why the hell do people still use Kick1.3 ?
- */
-
- static struct NewScreen ns = {
- 0,0, /* LeftEdge, TopEdge */
- 724,480, /* Width, Height */
- NS_DEPTH, /* Depth (16 EGA Colors) */
- 0,0, /* DetailPen, BlockPen */
- NS_VIEWMODE, /* ViewModes */ /* <graphics/view.h> */
- NS_TYPE, /* Type */
- NULL, /* Font */
- DisplayTitle, /* DefaultTitle */
- NULL, /* Gadgets */
- NULL, /* CustomBitMap */
- };
-
- static struct NewWindow nw = {
- 0,0, /* LeftEdge, TopEdge */
- 724,480, /* Width, Height */
- 1,2, /* DetailPen, BlockPen */
- NW_IDCMP, /* IDCMP Flags */
- NW_FLAGS, /* Flags */
- NULL, /* FirstGadget */
- NULL, /* CheckMark */
- NULL, /* Title */
- NULL, /* Screen */
- NULL, /* BitMap */
- -1,-1, /* MinWidth, MinHeight */
- -1,-1, /* MaxWidth, MaxHeight */
- NW_TYPE, /* Type */
- };
-
- /* EGA color table */
-
- static UWORD ega_rgb4[] = {
- 0x000, /* black */
- 0xA00, /* maroon */
- 0x0A0, /* dark green */
- 0xA60, /* orange */
- 0x00A, /* dark blue */
- 0xA0A, /* purple */
- 0x0AA, /* dark cyan */
- 0xBBB, /* light gray */
- 0x666, /* dark gray */
- 0xF00, /* red */
- 0x0F0, /* green */
- 0xFF0, /* yellow */
- 0x00F, /* blue */
- 0xF0F, /* magenta */
- 0x0FF, /* cyan */
- 0xFFF, /* white */
- };
-
- /*
- * AmigaSetPen will use the EGA pen number as an index in the egapen[] array
- * in order to obtain the (best) corresponding Amiga pen.
- * If bestpen[p] is >= 0 then we have *allocated* this pen and have to release
- * it in AmigaDisplayExit().
- */
-
- static int egapen[16] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
- static int bestpen[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- ULONG *DiskfontBase= (ULONG *)0;
- LONG __stack = 8192;
-
- /*
- ** 32x32x4 icon image created from `astrolog.ico'
- */
-
- static __chip const USHORT ico_data[] = {
- 0xe000, 0x0000, /* ###............................. */
- 0xf800, 0x0000, /* #####........................... */
- 0xfe20, 0x0000, /* #######...#..................... */
- 0x6f00, 0x0004, /* .##.####.....................#.. */
- 0x7380, 0x000e, /* .###..###...................###. */
- 0x31cf, 0xf004, /* ..##...###..########.........#.. */
- 0x38bf, 0xfc00, /* ..###...#.############.......... */
- 0x1c7f, 0xfe00, /* ...###...##############......... */
- 0x0eff, 0xff00, /* ....###.################........ */
- 0x07ff, 0xff80, /* .....####################....... */
- 0x07ff, 0xffc0, /* .....#####################...... */
- 0x03ff, 0xffc0, /* ......####################...... */
- 0x07ff, 0xffe0, /* .....######################..... */
- 0x07ff, 0xffe0, /* .....######################..... */
- 0x07ff, 0xffe0, /* .....######################..... */
- 0x07ff, 0xffe0, /* .....######################..... */
- 0x83ff, 0xffe0, /* #.....#####################..... */
- 0x01ff, 0xffe0, /* .......####################..... */
- 0x00ff, 0xffe0, /* ........###################..... */
- 0x00ff, 0xffe0, /* ........###################..... */
- 0x00ff, 0xffc0, /* ........##################...... */
- 0x01ff, 0xffc0, /* .......###################...... */
- 0x01ff, 0xffa2, /* .......##################.#...#. */
- 0x00ff, 0xff70, /* ........################.###.... */
- 0x207f, 0xfe38, /* ..#......##############...###... */
- 0x503f, 0xff1c, /* .#.#......##############...###.. */
- 0x200f, 0xf78c, /* ..#.........########.####...##.. */
- 0x0000, 0x01ce, /* .......................###..###. */
- 0x0000, 0x00f6, /* ........................####.##. */
- 0x0002, 0x007f, /* ..............#..........####### */
- 0x0000, 0x001f, /* ...........................##### */
- 0x0000, 0x0007, /* .............................### */
-
- 0x0000, 0x0000, /* ................................ */
- 0x0000, 0x0000, /* ................................ */
- 0x0020, 0x0000, /* ..........#..................... */
- 0x0000, 0x0004, /* .............................#.. */
- 0x0000, 0x000e, /* ............................###. */
- 0x000f, 0xf004, /* ............########.........#.. */
- 0x003f, 0xfc00, /* ..........############.......... */
- 0x007f, 0xfe00, /* .........##############......... */
- 0x00ff, 0xff00, /* ........################........ */
- 0x00ff, 0xff80, /* ........#################....... */
- 0x00ff, 0xffc0, /* ........##################...... */
- 0x007f, 0xffc0, /* .........#################...... */
- 0x063f, 0xffe0, /* .....##...#################..... */
- 0x071f, 0xffe0, /* .....###...################..... */
- 0x079f, 0xffe0, /* .....####..################..... */
- 0x078f, 0xffe0, /* .....####...###############..... */
- 0x83c7, 0xffe0, /* #.....####...##############..... */
- 0x1de3, 0xffe0, /* ...###.####...#############..... */
- 0x3ef1, 0xffe0, /* ..#####.####...############..... */
- 0x3ef8, 0xffe0, /* ..#####.#####...###########..... */
- 0x3efc, 0x7fc0, /* ..#####.######...#########...... */
- 0x1dfe, 0x1fc0, /* ...###.########....#######...... */
- 0x01ff, 0x0f82, /* .......#########....#####.....#. */
- 0x00ff, 0xc700, /* ........##########...###........ */
- 0x207f, 0xe000, /* ..#......##########............. */
- 0x503f, 0xf000, /* .#.#......##########............ */
- 0x200f, 0xf000, /* ..#.........########............ */
- 0x0000, 0x0000, /* ................................ */
- 0x0000, 0x0000, /* ................................ */
- 0x0002, 0x0000, /* ..............#................. */
- 0x0000, 0x0000, /* ................................ */
- 0x0000, 0x0000, /* ................................ */
-
- 0x0000, 0x0000, /* ................................ */
- 0x0000, 0x0000, /* ................................ */
- 0x0020, 0x0000, /* ..........#..................... */
- 0x0000, 0x0004, /* .............................#.. */
- 0x0000, 0x000e, /* ............................###. */
- 0x0000, 0x0004, /* .............................#.. */
- 0x0000, 0x0000, /* ................................ */
- 0x0000, 0x0000, /* ................................ */
- 0x0000, 0x003c, /* ..........................####.. */
- 0x0000, 0x003e, /* ..........................#####. */
- 0x0000, 0x001e, /* ...........................####. */
- 0x0000, 0x005e, /* .........................#.####. */
- 0x0000, 0x012e, /* .......................#..#.###. */
- 0x0000, 0x004c, /* .........................#..##.. */
- 0x0000, 0x00a0, /* ........................#.#..... */
- 0x0000, 0x0040, /* .........................#...... */
- 0x8000, 0x0120, /* #......................#..#..... */
- 0x1c00, 0x0040, /* ...###...................#...... */
- 0x3e00, 0x00a0, /* ..#####.................#.#..... */
- 0x3e00, 0x0040, /* ..#####..................#...... */
- 0x3e00, 0x0100, /* ..#####................#........ */
- 0x1c00, 0x0000, /* ...###.......................... */
- 0x0000, 0x0002, /* ..............................#. */
- 0x0000, 0x0000, /* ................................ */
- 0x2000, 0x0000, /* ..#............................. */
- 0x5000, 0x0000, /* .#.#............................ */
- 0x2000, 0x0000, /* ..#............................. */
- 0x0000, 0x0000, /* ................................ */
- 0x0000, 0x0000, /* ................................ */
- 0x0002, 0x0000, /* ..............#................. */
- 0x0000, 0x0000, /* ................................ */
- 0x0000, 0x0000, /* ................................ */
-
- 0x6000, 0x0040, /* .##......................#...... */
- 0xf000, 0x4000, /* ####.............#.............. */
- 0xdc20, 0x0000, /* ##.###....#..................... */
- 0x6900, 0x0200, /* .##.#..#..............#......... */
- 0x3200, 0x0000, /* ..##..#......................... */
- 0x3009, 0x5000, /* ..##........#..#.#.#............ */
- 0x1802, 0xbc00, /* ...##.........#.#.####.......... */
- 0x1c15, 0x6e00, /* ...###.....#.#.#.##.###......... */
- 0x0e02, 0xbf0c, /* ....###.......#.#.######....##.. */
- 0x0729, 0x5f86, /* .....###..#.#..#.#.######....##. */
- 0x0702, 0xbfce, /* .....###......#.#.########..###. */
- 0x0395, 0x6fc6, /* ......###..#.#.#.##.######...##. */
- 0x01c2, 0xbfee, /* .......###....#.#.#########.###. */
- 0x00e9, 0x57e4, /* ........###.#..#.#.#.######..#.. */
- 0x0062, 0xbfe0, /* .........##...#.#.#########..... */
- 0x0075, 0x6fe0, /* .........###.#.#.##.#######..... */
- 0x803a, 0xbfe0, /* #.........###.#.#.#########..... */
- 0x0c1d, 0x5fe0, /* ....##.....###.#.#.########..... */
- 0x060e, 0xbfe1, /* .....##.....###.#.#########....# */
- 0x0e07, 0x7fe0, /* ....###......###.##########..... */
- 0x0643, 0xb7c0, /* .....##..#....###.##.#####...... */
- 0x0c15, 0xffc0, /* ....##.....#.#.###########...... */
- 0x0002, 0xffa2, /* ..............#.#########.#...#. */
- 0x0029, 0x7f70, /* ..........#.#..#.#######.###.... */
- 0x0002, 0xbe38, /* ..............#.#.#####...###... */
- 0x2015, 0x5f18, /* ..#........#.#.#.#.#####...##... */
- 0x0002, 0xb78c, /* ..............#.#.##.####...##.. */
- 0x0080, 0x01cc, /* ........#..............###..##.. */
- 0x0000, 0x00f6, /* ........................####.##. */
- 0x0000, 0x003b, /* ..........................###.## */
- 0x0000, 0x020f, /* ......................#.....#### */
- 0x0800, 0x0006, /* ....#........................##. */
- };
-
-
- static struct Image ico = {
- 0, /* LeftEdge */
- 0, /* TopEdge */
- 32, /* Width */
- 32, /* Height */
- 4, /* Depth */
- &ico_data[0], /* ImageData */
- 0x0F, /* PlanePick */
- 0x00, /* PlaneOnOff */
- NULL /* NextImage */
- };
-
- extern struct Image icon_image; /* xscreen.c */
-
- /*
- ** CODE
- */
-
- #define ERR_NO_INTITION 1
- #define ERR_NO_GRAPHICS 2
- #define ERR_NO_SCREEN 3
- #define ERR_NO_WINDOW 4
-
- /*
- * These variables are used to save those settings which might
- * get modified via AmigaDisplayInit(). They are restored by
- * AmigaDisplayExit()
- */
-
- static int gs_xWin, gs_yWin, gi_xOffset, gi_yOffset, us_fAnsi;
-
- /****** amiga/AmigaDisplayInit ***********************************************
- *
- * NAME
- * AmigaDisplayInit -- Initialize an Amiga screen for Astrolog charts
- *
- * SYNOPSIS
- * error= AmigaDisplayInit();
- *
- * int AmigaDisplayInit(void);
- *
- * FUNCTION
- * This function opens an Amiga screen with an EGA palette and a sizable
- * window which is large enough to hold `gs.xWin' pixel columns and
- * `gs.yWin' pixel rows. If this should fail for any reason, an error
- * code != 0 is returned.
- *
- * INPUTS
- * none
- *
- * RESULT
- * error - != 0 in case of an error, 0 otherwise
- *
- * EXAMPLE
- * #include "astrolog.h"
- *
- * \* ... *\
- *
- * if( AmigaDisplayInit() == 0 )
- * {
- * \* do some gfx... *\
- *
- * AmigaDisplayExit();
- * }
- * else error();
- *
- * NOTES
- * Hack: The EGA colors provided for the screen are taken from the
- * global rgbbmp[] array (see xdata.c). However, if the `us.fAnsi' flag
- * is set, a slightly brighter palette is used.
- *
- * Note also that this function sets `us.fAnsi' to `fFalse' to make sure
- * that no ANSI characters are used in the graphic chart mode. The
- * initial value of `us.fAnsi' is resored by AmigaDisplayExit().
- *
- * BUGS
- *
- * SEE ALSO
- * AmigaDisplayExit()
- *
- ******************************************************************************
- *
- * #define SPREAD(v) ((ULONG)(v)<<24 | (ULONG)(v)<<16 | (ULONG)(v)<<8 | (v))
- *
- * SetRGB32(vp,0,SPREAD(255),SPREAD(255),SPREAD(255));
- *
- */
-
-
- /* scale an RGB4 fraction to RGB32 */
-
- static long scale_rgb4(short v4)
- {
- long v32= 0;
- int i;
-
- for(i=0; i<8; i++)
- v32 = (v32<<4) | v4;
-
- return v32;
- }
-
- int AmigaDisplayInit()
- {
- struct Screen *s;
- struct Window *w;
-
- int err= 0;
-
- /* save initial values */
-
- gs_xWin = gs.xWin; gi_xOffset = gi.xOffset;
- gs_yWin = gs.yWin; gi_yOffset = gi.yOffset;
-
- /* Astrolog problem: Ansi characters not defined in the internal vector font */
-
- us_fAnsi = us.fAnsi; us.fAnsi = fFalse;
-
- /*printf("AmigaDisplayInit() requested display geometry: %dx%d\n",gs.xWin,gs.yWin);*/
-
- if( (IntuitionBase= (struct IntuitionBase *)OpenLibrary("intuition.library",0L)) )
- {
- if( (GfxBase= (struct GfxBase *)OpenLibrary("graphics.library",0L)) )
- {
- /*
- * Die beiden printf()s zeigen, daß man hier eins addieren muß um am Ende
- * die tatsächlich gewünschte größe zu erhalten...
- */
-
- ns.Width = nw.Width = gs.xWin +1;
- ns.Height = nw.Height = gs.yWin +1;
-
- nw.MaxWidth = BITMAPX; nw.MaxHeight = BITMAPY;
- nw.MinWidth = BITMAPX1; nw.MinHeight = BITMAPY1;
-
- #if !defined(NOSCREEN)
- /*
- ** Should we better try to clone the Workbench screen?
- */
-
- if (IntuitionBase->LibNode.lib_Version <= 34)
- s= (struct Screen *)OpenScreen(&ns);
-
- else /* Kickstart 2.0+ */
- {
- static struct TagItem scrtaglist[] = { {SA_Overscan,OSCAN_TEXT},{TAG_DONE,0} };
-
- /*ns.Width = STDSCREENWIDTH;*/
- /*ns.Height = STDSCREENHEIGHT;*/
-
- s= OpenScreenTagList(&ns,scrtaglist);
- }
-
- if(s)
- {
- if(us_fAnsi == fFalse) /* hack! */
- {
- /* create a new colormap from `xdata.c' which is slightly darker than the one above */
-
- int i;
- for(i=0; i<(1<<ns.Depth); i++)
- {
- UWORD r= (rgbbmp[i] & 0x0000FF) / 0x10;
- UWORD g= ((rgbbmp[i] & 0x00FF00) >> 8) / 0x10;
- UWORD b= ((rgbbmp[i] & 0xFF0000) >> 16) / 0x10;
-
- ega_rgb4[i]= (r<<8) | (g<<4) | b;
- /*printf("ega_rgb4[%d] = 0x%03x\n",i,ega_rgb4[i]);*/
- }
- }
-
- ShowTitle(s,FALSE);
- LoadRGB4(&s->ViewPort, ega_rgb4, 1<<(ns.Depth));
- nw.Screen= s;
-
- #else /* NOSCREEN */
- if(1)
- {
- nw.Screen = (struct Screen *)0;
- nw.Type = WBENCHSCREEN;
- nw.Title = /*ns.DefaultTitle*/ DisplayTitle;
-
- s= LockPubScreen( NULL );
- #endif /* NOSCREEN */
-
- if(nw.Width > s->Width) nw.Width = s->Width;
- if(nw.Height > s->Height) nw.Height = s->Height;
-
- if( (w= (struct Window *)OpenWindow(&nw)) )
- {
- int xmin= (int)(w->BorderLeft);
- int ymin= (int)(w->BorderTop);
- int xmax= (int)(w->Width - w->BorderRight - 1);
- int ymax= (int)(w->Height - w->BorderBottom - 1);
-
- gi.xOffset = xmin;
- gi.yOffset = ymin;
-
- gs.xWin = xmax - xmin;
- gs.yWin = ymax - ymin;
-
- #if defined(NOSCREEN)
- UnlockPubScreen( NULL, s );
- s= w->WScreen;
- #endif /* NOSCREEN */
-
- gi.scr = s;
- gi.win = w;
- gi.rp = w->RPort; gi.paging = 0; /* <-- */
-
- /*printf("AmigaDisplayInit() allocated display geometry: %dx%d\n",gs.xWin,gs.yWin);*/
-
- #if !defined(NOSCREEN)
- /*
- ** SetRast() können wir hier nur deshalb benutzen, weil wir die
- ** Window Border sowieso nicht sehen wollen...
- */
-
- SetRast(w->RPort, 0L);
-
- #else /* NOSCREEN */
- {
- struct ColorMap *cm= w->WScreen->ViewPort.ColorMap;
- int p;
-
- for(p=0; p<16; p++)
- {
- long r,g,b;
-
- r= scale_rgb4( (ega_rgb4[p] & 0x0F00) >> 8 );
- g= scale_rgb4( (ega_rgb4[p] & 0x00F0) >> 4 );
- b= scale_rgb4( (ega_rgb4[p] & 0x000F) );
-
- bestpen[p]= ObtainBestPen( cm, r,g,b, OBP_Precision, PRECISION_GUI, TAG_END );
-
- if(bestpen[p] >= 0)
- egapen[p]= bestpen[p];
- }
- }
- #endif /* NOSCREEN */
- }
-
- else /* OpenWindow() failed */
- {
- #if !defined(NOSCREEN)
- CloseScreen(s);
- #endif /* !NOSCREEN */
- err= ERR_NO_WINDOW;
- }
- }
- else /* OpenScreen() failed */
- err= ERR_NO_SCREEN;
- }
- }
-
- return err;
- }
-
- /****** amiga/AmigaDisplayPaging *********************************************
- *
- * NAME
- * AmigaDisplayPaging -- Allocate or free the page for animations
- *
- * SYNOPSIS
- * paging= AmigaDisplayPaging();
- *
- * int AmigaDisplayPaging(void);
- *
- * FUNCTION
- * Here we allocate a 2nd rastport for double buffering. All Amiga
- * drawing happens in `gi.rp' and here we replace `gi.rp' with a newly
- * allocated rastport which has the same size as the one of the astrolog
- * screen `gi.scr'. Since paging is mainly used for animation purposes,
- * we also add the INTUITICKS bit to our window's IDCMP port.
- * Failure due to low memory is no fatal error because double buffering is
- * only a bonus for the animations.
- *
- * INPUTS
- * none
- *
- * RESULT
- * paging - 0 if we disabled paging with this call, !=0 otherwise.
- *
- * EXAMPLE
- * #include "astrolog.h"
- *
- * \* ... *\
- *
- * if( AmigaDisplayInit() == 0 )
- * {
- * \* switch to double buffering mode *\
- *
- * if(!gi.paging)
- * AmigaDisplayPaging();
- *
- * \* do some anim stuff... *\
- *
- * AmigaDisplayExit();
- * }
- * else error();
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * AmigaDisplayPaging(), AmigaDisplayExit()
- *
- ******************************************************************************
- *
- *
- */
-
- int AmigaDisplayPaging(void)
- {
- if(gi.paging)
- {
- rp_dispose(gi.rp);
- gi.rp= (gi.win)->RPort;
- gi.paging= 0;
-
- ModifyIDCMP(gi.win, (gi.win->IDCMPFlags) & ~INTUITICKS);
- }
- else /* !gi.paging */
- {
- struct RastPort *rp= rp_new(gi.scr->Width, gi.scr->Height, gi.scr->RastPort.BitMap->Depth);
-
- if(rp)
- {
- gi.rp= rp;
- gi.paging= 1;
-
- ModifyIDCMP(gi.win, (gi.win->IDCMPFlags) | INTUITICKS);
- }
- }
- return gi.paging;
- }
-
-
- /****** amiga/AmigaDisplayExit ***********************************************
- *
- * NAME
- * AmigaDisplayExit -- Dispose Astrolog's Amiga graphics stuff
- *
- * SYNOPSIS
- * AmigaDisplayExit();
- *
- * void AmigaDisplayExit(void);
- *
- * FUNCTION
- * This function closes Astrolog's window and screen which had been
- * provided via AmigaDisplayInit(). If paging is on, i.e. a 2nd
- * page has been provided for animations, then this page is disposed
- * as well.
- *
- * INPUTS
- * none
- *
- * RESULT
- * none
- *
- * EXAMPLE
- * #include "astrolog.h"
- *
- * \* ... *\
- *
- * if( AmigaDisplayInit() == 0 )
- * {
- * \* do some gfx... *\
- *
- * AmigaDisplayExit();
- * }
- * else error();
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * AmigaDisplayInit()
- *
- ******************************************************************************
- *
- *
- */
-
- void AmigaDisplayExit()
- {
- if(gi.paging)
- {
- AmigaDisplayPaging();
- }
-
- #if defined(NOSCREEN)
- {
- struct ColorMap *cm= (gi.win)->WScreen->ViewPort.ColorMap;
- int p;
-
- for(p=0; p<16; p++)
- if(bestpen[p] >= 0)
- ReleasePen(cm,bestpen[p]);
- }
- #endif /* NOSCREEN */
-
- if(gi.win)
- {
- /*CloseWindow(gi.win);*/
- CloseWindowSafely(gi.win);
- gi.win= (struct Window *)0;
- }
-
- #if !defined(NOSCREEN)
- if(gi.scr)
- {
- CloseScreen(gi.scr);
- gi.scr= (struct Screen *)0;
- }
- #endif /* !NOSCREEN */
-
- if(GfxBase)
- {
- CloseLibrary((struct Library *)GfxBase);
- GfxBase= (struct GfxBase *)0;
- }
-
- if(IntuitionBase)
- {
- CloseLibrary((struct Library *)IntuitionBase);
- IntuitionBase= (struct IntuitionBase *)0;
- }
-
- /* restore initial values */
-
- gs.xWin = gs_xWin; gi.xOffset = gi_xOffset;
- gs.yWin = gs_yWin; gi.yOffset = gi_yOffset;
-
- us.fAnsi = us_fAnsi;
- }
-
- /****** amiga/AmigaDisplayUpdate *********************************************
- *
- * NAME
- * AmigaDisplayUpdate -- Display the temporary drawing page
- *
- * SYNOPSIS
- * AmigaDisplayUpdate();
- *
- * void AmigaDisplayUpdate(void);
- *
- * FUNCTION
- * If double buffering is enabled, then the hidden page (which is the
- * one we use to paint on) will be copied to the currently visible page.
- * Without any 2nd page, calling this procedure is a no-op.
- *
- * INPUTS
- * none
- *
- * RESULT
- * none
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * AmigaDisplayPaging()
- *
- ******************************************************************************
- *
- *
- */
-
- void AmigaDisplayUpdate(void)
- {
- if(gi.paging)
- ClipBlit(gi.rp, 0,0, gi.win->RPort, 0,0, gi.win->Width,gi.win->Height, 0xc0);
- }
-
-
- /****** amiga/AmigaClearScreen ***********************************************
- *
- * NAME
- * AmigaClearScreen -- Clear Astrolog's Amiga graphics display
- *
- * SYNOPSIS
- * AmigaClearScreen();
- *
- * void AmigaClearScreen(void);
- *
- * FUNCTION
- * This procedure unsets all pixels in the drawing page.
- *
- * INPUTS
- * none
- *
- * RESULT
- * none
- *
- * EXAMPLE
- *
- * NOTES
- * Calling this function is usually faster than painting a rectangle
- * covering the whole screen.
- *
- * BUGS
- *
- * SEE ALSO
- * AmigaDisplayPaging()
- *
- ******************************************************************************
- *
- *
- */
-
- void AmigaClearScreen(void)
- {
-
- #if defined(NOSCREEN)
- if(gi.win && gi.rp)
- {
- struct RastPort *rp= gi.rp;
- struct Window *w= gi.win;
-
- SHORT xmin= (SHORT)(w->BorderLeft);
- SHORT ymin= (SHORT)(w->BorderTop);
- SHORT xmax= (SHORT)(w->Width - w->BorderRight - 1);
- SHORT ymax= (SHORT)(w->Height - w->BorderBottom - 1);
-
- SetAPen(rp,0L);
- RectFill(rp, xmin,ymin, xmax,ymax);
- }
- #else /* !NOSCREEN */
- SetRast(gi.rp,0L);
- #endif /* !NOSCREEN */
- }
-
- /****** amiga/AmigaDisplayResize *********************************************
- *
- * NAME
- * AmigaDisplayResize -- Guarantee certain graphic display dimensions
- *
- * SYNOPSIS
- * error= AmigaDisplayResize(width, height);
- *
- * int AmigaDisplayResize(int, int);
- *
- * FUNCTION
- * This function makes sure that the Amiga graphics page (screen and
- * window) are large enough to hold a graphic with `width' pixels
- * horizontally and `height' pixels vertically. If the current screen
- * is large enough, nothing happens. Otherwise it will be enlarged
- * to the given size.
- *
- * INPUTS
- * none
- *
- * RESULT
- * error - != 0 in case of an error, 0 otherwise
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * AmigaDisplayInit(), AmigaDisplayExit()
- *
- ******************************************************************************
- *
- *
- */
-
- int AmigaDisplayResize(int width, int height)
- {
- int err= 0;
-
- /* We only have to close screen and window if we must enlarge the display */
-
- if( (width > (gi.win)->Width) || (height > (gi.win)->Height) )
- {
- int p= gi.paging;
-
- AmigaDisplayExit();
-
- if(width > gs.xWin) gs.xWin= width;
- if(height > gs.yWin) gs.yWin= height;
-
- err= AmigaDisplayInit();
-
- if(!err && p)
- AmigaDisplayPaging();
- }
-
- /*
- ** Now that we can be sure that the display is large enough, we fake
- ** the exact desired dimensions
- */
-
- gs.xWin= width;
- gs.yWin= height;
-
- return err;
- }
-
- /****** amiga/AmigaGetKey ****************************************************
- *
- * NAME
- * AmigaGetKey -- Wait for a keypress and return it's ASCII code
- *
- * SYNOPSIS
- * key= AmigaGetKey();
- *
- * int AmigaGetKey(void);
- *
- * FUNCTION
- * Wait for a keypress and return the ASCII code of that key. This
- * function distinguishes between console mode and graphics mode and
- * calls getkey() if there is no graphics window.
- *
- * INPUTS
- * none
- *
- * RESULT
- * key - The ASCII code of the character on the pressed key
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- * getkey()
- *
- ******************************************************************************
- *
- *
- */
-
- int AmigaGetKey(void)
- {
- int key= '\0';
-
- if(gi.win)
- {
- struct Window *w= gi.win;
-
- while(!key)
- {
- ULONG sig= Wait( SIGBREAKF_CTRL_C | (1L<<w->UserPort->mp_SigBit) );
-
- if( sig & SIGBREAKF_CTRL_C )
- key= '\003';
-
- if( sig & (1L<<w->UserPort->mp_SigBit) )
- {
- struct IntuiMessage *imsg;
-
- while( (imsg=(struct IntuiMessage *)GetMsg(w->UserPort)) )
- {
- ULONG class = imsg->Class;
- USHORT code = imsg->Code;
-
- ReplyMsg((struct Message *)imsg);
-
- switch(class)
- {
- case VANILLAKEY:
- key= (int)code;
- break;
- }
- }
- }
- }
- }
- else /* !gi.win */
- key= getkey();
-
- return key;
- }
-
-
- /*
- ** undocumented hacks...
- */
-
- void AmigaSetPen(int pen) { SetAPen(gi.rp,egapen[pen]); }
-
- int AmigaMaxDisplayRows(void)
- {
- int result= 2730;
-
- if(gi.scr)
- {
- result= (gi.scr)->Height;
- }
-
- else /* !gi.scr */
- {
- if(IntuitionBase)
- {
- struct Screen *s= LockPubScreen( NULL );
-
- if(s)
- result= s->Height;
-
- UnlockPubScreen( NULL, s );
- }
- }
-
- return result;
- }
-
-
- int AmigaMaxDisplayColumns(void)
- {
- int result= 2730;
-
- if(gi.scr)
- {
- result= (gi.scr)->Width;
- }
-
- else /* !gi.scr */
- {
- if(IntuitionBase)
- {
- struct Screen *s= LockPubScreen( NULL );
-
- if(s)
- result= s->Width;
-
- UnlockPubScreen( NULL, s );
- }
- }
-
- return result;
- }
-
-
-
- char *AmigaGetString(char *buf)
- {
- int key, n=0;
-
- do
- {
- key= AmigaGetKey();
-
- if(32 <= key && key <= 127)
- {
- buf[n++]= key;
- xPrint("%c",key);
- }
-
- else if(key=='\b')
- {
- if(n>0)
- {
- int pen= gi.kiCur;
-
- --n;
-
- DrawColor(gi.kiOff);
- xPrint("\b%c\b",buf[n]);
- DrawColor(pen);
- }
- else DisplayBeep(gi.scr);
- }
-
- else if(key=='\n' || key=='\r')
- {
- buf[n]= '\0';
- }
- else DisplayBeep(gi.scr);
-
- } while(key!='\n' && key!='\r');
-
- return buf;
- }
-
-
- /**/
-
- int AmigaDisplayDebug(void)
- {
- AmigaClearScreen();
- DrawImage(gi.rp, &ico, gs.xWin-ico.Width, 0);
- /*DrawImage(gi.rp, &icon_image, gs.xWin-icon_image.Width,100);*/
-
- xPrintAt(1,1,"");
-
- /*
- * Who is the first to blame me for this abuse of the `-k' switch (-;
- */
-
- if(us_fAnsi)
- {
- DiskfontBase= (struct DiskfontBase *)OpenLibrary("diskfont.library",0L);
-
- if(DiskfontBase)
- {
- static struct TextAttr ta = { "CGTimes.font", 70, FS_NORMAL, FPF_DISKFONT };
- struct TextFont *tf;
-
- xPrintAt(1,1,"{green}Computing `{white}%s{green}' ({white}%d{green}) ... Please Wait ...",ta.ta_Name,ta.ta_YSize);
-
- if( (tf= OpenDiskFont(&ta)) )
- {
- struct RastPort *rp= gi.rp;
- char *str= "Astrolog";
- int L= strlen(str);
- int l,x,y;
-
- xPrintAt(1,1,"{black}Computing `%s' (%d) ... Please Wait ...",ta.ta_Name,ta.ta_YSize);
-
- DrawImage(rp, &ico, 0,0);
- DrawImage(rp, &ico, gs.xWin-ico.Width, 0);
-
- SetFont(rp,tf);
-
- l= TextLength(rp,str,L);
- x= (gs.xWin-l)/2;
- y= tf->tf_Baseline+1;
-
- /* smoothing via outline */
-
- DrawColor(kLtGray); SetDrMd(gi.rp,JAM1);
- /*Move(rp, x-1,y-1); Text(rp,str,L);*/
- Move(rp, x ,y-1); Text(rp,str,L);
- Move(rp, x+1,y-1); Text(rp,str,L);
- Move(rp, x-1,y ); Text(rp,str,L);
- Move(rp, x+1,y ); Text(rp,str,L);
- Move(rp, x-1,y+1); Text(rp,str,L);
- Move(rp, x ,y+1); Text(rp,str,L);
- /*Move(rp, x+1,y+1); Text(gi.rp,str,L);*/
-
- DrawColor(kWhite);
- Move(gi.rp, x,y);
- Text(gi.rp,str,L);
-
- DrawColor(kRed);
- DrawLine(0,tf->tf_YSize+5, gs.xWin,tf->tf_YSize+5);
-
- CloseFont(tf);
-
- xPrintAt(9,1,"");
- }
- else
- xPrint(" {red}failed.\n\n");
-
- CloseLibrary(DiskfontBase);
- }
- else xPrintAt(1,1,"{red}Warning: could not open {white}diskfont.library{red}!\n");
- }
-
- xPrint("{white}** %s version %s **\n", szAppName, szVersionCore);
- xPrint("{ltgray}As of %s (compiled %s, %s)\n", szDateCore, __DATE__, __TIME__);
- xPrint("{cyan}By Walter D. Pullen (%s)\n", szAddressCore);
- xPrint("{yellow}Amiga port by Tobias Ferber (tf@antares.ping.de)\n");
-
- xPutString("\n\n");
-
- {
- /* Graphics chart modes */
-
- static char *gcm[] = {
- "<unknown>", /* 0 */
- "gWheel", /* 1 */
- "gHouse", /* 2 */
- "gGrid", /* 3 */
- "gHorizon", /* 4 */
- "gOrbit", /* 5 */
- "gAstroGraph", /* 6 */
- "gEphemeris", /* 7 */
- "gWorldMap", /* 8 */
- "gGlobe", /* 9 */
- "gPolar", /* 10 */
- "gBiorhythm", /* 11 */
- "gCalendar", /* 12 */
- "gDisposit", /* 13 */
- };
-
- xPrint("{red}Internal settings page called from graphic chart mode {white}%d{red} ({white}%s{red})\n",
- gi.nMode, gcm[gi.nMode]);
- }
-
- xPutString("\n");
-
- {
- struct Window *w= gi.win;
-
- xPrint("{green}Current window geometry: {white}%d{green}x{white}%d{green}x{white}%d"
- "{green}, borders (left,top,right,bottom): {white}%d{green},{white}%d{green},{white}%d{green},{white}%d\n",
- w->Width, w->Height, w->RPort->BitMap->Depth,
- w->BorderLeft, w->BorderTop, w->BorderRight, w->BorderBottom);
-
- xPrint("{green}Resulting maximum playfield: ({white}%d{green},{white}%d{green}) .. ({white}%d{green},{white}%d{green}) [geometry {white}%d{green}x{white}%d{green}]\n",
- w->BorderLeft,
- w->BorderTop,
- w->Width - w->BorderRight - 1,
- w->Height - w->BorderBottom - 1,
- w->Width - w->BorderRight - 1 - w->BorderLeft,
- w->Height - w->BorderBottom - 1 - w->BorderTop);
-
- xPrint("{green}Actually used playfield: ({white}%d{green},{white}%d{green}) .. ({white}%d{green},{white}%d{green}) [geometry {white}%d{green}x{white}%d{green}]\n",
- gi.xOffset,gi.yOffset, gs.xWin,gs.yWin,gs.xWin-gi.xOffset,gs.yWin-gi.yOffset);
-
- xPrint("{green}Paging is {white}%s{green} for animation mode {white}%d{green}.\n",
- gi.paging ? "enabled" : "disabled", gs.nAnim);
- }
-
- xPutString("\n");
-
- {
- xPrint("{green}"
- "EGA Colors: " "{black}" "black, "
- "{maroon}" "maroon, "
- "{dkgreen}" "dkgreen, "
- "{orange}" "orange, "
- "{dkblue}" "dkblue, "
- "{purple}" "purple, "
- "{dkcyan}" "dkcyan, "
- "{ltgray}" "ltgray, " "\n"
- " " "{dkgray}" "dkgray, "
- "{red}" "red, "
- "{green}" "green, "
- "{yellow}" "yellow, "
- "{blue}" "blue, "
- "{magenta}" "magenta, "
- "{cyan}" "cyan, "
- "{white}" "white. " "\n");
- }
-
- xPutString("\n");
-
- {
- ULONG chip= AvailMem(MEMF_CHIP);
- ULONG fast= AvailMem(MEMF_FAST);
-
- xPrint("{cyan}Available memory: {white}%ld{cyan} bytes (CHIP: {white}%ld{cyan}, FAST: {white}%ld{cyan})\n",
- chip,fast,chip+fast);
-
- chip= AvailMem(MEMF_CHIP|MEMF_LARGEST);
- fast= AvailMem(MEMF_FAST|MEMF_LARGEST);
-
- xPrint("{cyan}Largest available memory block: {white}%ld{cyan} bytes CHIP, {white}%ld{cyan} bytes FAST.\n",
- chip,fast);
- }
-
- xPutString("\n");
-
- if(!gi.paging)
- {
- /*
- ** Taken from CommandLineX()
- */
-
- char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
- int argc, fT;
-
- ciCore = ciMain;
- fT = us.fLoop; us.fLoop = fTrue;
- argc = NPromptSwitches(szCommandLine, rgsz);
- is.cchRow = 0;
- is.fSzInteract = fTrue;
-
- if( FProcessSwitches(argc, rgsz) )
- {
- is.fMult = fFalse;
- FPrintTables();
-
- if (is.fMult)
- {
- ClearB((lpbyte)&us.fCredit, (int)((lpbyte)&us.fLoop - (lpbyte)&us.fCredit));
- }
- }
-
- is.fSzInteract = fFalse;
- us.fLoop = fT;
- ciMain = ciCore;
- }
-
- xPutString("{magenta}Press any key to continue (or any other to resume) ...");
- AmigaDisplayUpdate();
- return AmigaGetKey();
- }
-
- /* Generic NDK Code */
-
- #include "exec/types.h"
- #include "exec/nodes.h"
- #include "exec/lists.h"
- #include "exec/ports.h"
- #include "intuition/intuition.h"
-
- /*
- * Remove and reply all IntuiMessages on a port that have been sent to a particular window
- * ( note that we don't rely on the ln_Succ pointer of a message after we have replied it )
- */
-
- void
- StripIntuiMessages( mp, win )
- struct MsgPort *mp;
- struct Window *win;
- {
- struct IntuiMessage *msg;
- struct Node *succ;
-
- msg= (struct IntuiMessage *)mp->mp_MsgList.lh_Head;
-
- while( (succ= msg->ExecMessage.mn_Node.ln_Succ) )
- {
- if( msg->IDCMPWindow == win )
- {
- /* Intuition is about to free this message.
- * Make sure that we have politely sent it back.
- */
- Remove( (struct Node *)msg );
- ReplyMsg( (struct Message *)msg );
- }
-
- msg= (struct IntuiMessage *)succ;
- }
- }
-
- /*
- * These functions close an Intuition window that shares a port with other Intuition
- * windows or IPC customers.
- *
- * We are careful to set the UserPort to null before closing, and to free
- * any messages that it might have been sent.
- */
-
- void
- CloseWindowSafely( struct Window *win )
- {
- /* we forbid here to keep out of race conditions with Intuition */
- Forbid();
-
- /* send back any messages for this window
- * that have not yet been processed
- */
- StripIntuiMessages( win->UserPort, win );
-
- /* tell Intuition to stop sending more messages */
- ModifyIDCMP( win, 0L );
-
- /* turn multitasking back on */
- Permit();
-
- /* and really close the window */
- CloseWindow( win );
- }
-